# -*- coding: utf-8 -*- 
"""
Project: AppleSnApi
Creator: SF
Create time: 2025-06-24 16:50
IDE: PyCharm
Introduction: 监测系统的运行状况
"""
import json
from bs4 import BeautifulSoup
import sys
import os
import requests

current_path = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(current_path)[0]
sys.path.append(rootPath)

from settings import FILE_DIR

# 模板文件
template_html = """
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>国补SN-系统节点监控面板</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

  <!-- 配置Tailwind自定义样式 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#3B82F6',
            secondary: '#10B981',
            accent: '#8B5CF6',
            danger: '#EF4444',
            warning: '#F59E0B',
            success: '#10B981',
            dark: '#1F2937',
            light: '#F3F4F6'
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
        },
      }
    }
  </script>

  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .node-card {
        @apply bg-white rounded-xl shadow-md hover:shadow-lg transition-all duration-300 border border-gray-100;
      }
      .metric-card {
        @apply bg-white rounded-lg shadow-sm p-4 transition-all duration-200 border border-gray-100;
      }
      .stat-value {
        @apply text-xl font-bold;
      }
      .stat-label {
        @apply text-sm text-gray-500 uppercase tracking-wider;
      }
      .status-dot {
        @apply inline-block w-3 h-3 rounded-full mr-2;
      }
      .info-item {
        @apply py-2 border-b border-gray-100 flex justify-between;
      }
      .info-label {
        @apply text-gray-500 text-sm;
      }
      .info-value {
        @apply font-medium;
      }
      .usage-badge {
        @apply px-2 py-0.5 rounded-full text-xs font-medium;
      }
      .loading-spinner {
        @apply animate-spin inline-block w-4 h-4 border-2 border-primary border-t-transparent rounded-full;
      }
    }
  </style>
</head>

<body class="bg-gray-50 font-inter text-dark min-h-screen">
  <!-- 顶部导航栏 -->
  <header class="bg-white shadow-md sticky top-0 z-50">
    <div class="container mx-auto px-4 py-3 flex justify-between items-center">
      <div class="flex items-center space-x-2">
        <i class="fa fa-server text-primary text-2xl"></i>
        <h1 class="text-xl font-bold text-dark">系统节点监控面板</h1>
      </div>
      <div class="flex items-center space-x-4">
        <div class="relative">
          <input type="text" id="search-node" placeholder="搜索节点..."
            class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary">
          <i class="fa fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
        </div>
      </div>
    </div>
  </header>

  <main class="container mx-auto px-4 py-6">
    <!-- 概览统计 -->
    <section class="mb-8">
      <h2 class="text-xl font-semibold mb-4 flex items-center">
        <i class="fa fa-tachometer text-accent mr-2"></i>系统概览
      </h2>
      <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
        <div class="metric-card">
          <div class="stat-label">成功查询数</div>
          <div class="stat-value text-secondary" id="success-count">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">今日查询成功数</div>
          <div class="stat-value text-warning" id="today_count">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">近三日查询成功数</div>
          <div class="stat-value text-warning" id="three_days_count">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">总体失败数</div>
          <div class="stat-value text-danger" id="failed-count">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">无效SN数</div>
          <div class="stat-value text-primary" id="valid-sn">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">未激活数量</div>
          <div class="stat-value text-primary" id="no-active">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">OCR识别有误</div>
          <div class="stat-value text-warning" id="ocr-error">0</div>
        </div>
        <div class="metric-card">
          <div class="stat-label">获取验证码失败</div>
          <div class="stat-value text-warning" id="input_captcha_error">0</div>
        </div>
      </div>
    </section>

    <!-- 服务器信息 -->
    <section class="mb-8">
      <h2 class="text-xl font-semibold mb-4 flex items-center">
        <i class="fa fa-desktop text-secondary mr-2"></i>Server Node
      </h2>
      <div id="server-card" class="node-card">
        <div class="p-5 border-b border-gray-100">
          <div class="flex justify-between items-start">
            <div>
              <h3 class="text-lg font-semibold">服务器信息</h3>
              <p class="text-gray-500 text-sm" id="server-hostname">加载中...</p>
            </div>
            <span class="bg-primary/10 text-primary text-xs font-medium px-2.5 py-0.5 rounded" id="server-ip">--</span>
          </div>
        </div>

        <div class="p-5 space-y-4">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div class="info-item">
              <div class="info-label">操作系统</div>
              <div class="info-value" id="server-os">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">系统版本</div>
              <div class="info-value" id="server-os-version">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">Python版本</div>
              <div class="info-value" id="server-python-version">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">当前时间</div>
              <div class="info-value" id="server-current-time">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">运行时间</div>
              <div class="info-value" id="server-uptime">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">进程总数</div>
              <div class="info-value" id="server-process-count">--</div>
            </div>
            <!-- 添加CPU和内存使用率 -->
            <div class="info-item">
              <div class="info-label">CPU使用率</div>
              <div class="info-value" id="server-cpu-usage">--</div>
            </div>
            <div class="info-item">
              <div class="info-label">内存使用率</div>
              <div class="info-value" id="server-mem-usage">--</div>
            </div>
          </div>

          <div class="border-t border-gray-100 pt-4 mt-4">
            <h4 class="font-medium mb-3 flex items-center">
              <i class="fa fa-cog text-primary mr-2"></i>目标进程状态
            </h4>
            <div class="space-y-3">
              <div class="info-item">
                <div class="info-label">运行状态</div>
                <div class="info-value" id="server-process-status">--</div>
              </div>
              <div class="info-item">
                <div class="info-label">进程ID</div>
                <div class="info-value" id="server-process-pid">--</div>
              </div>
              <div class="info-item">
                <div class="info-label">命令行</div>
                <div class="info-value text-sm" id="server-process-cmdline">--</div>
              </div>
              <div class="info-item">
                <div class="info-label">启动时间</div>
                <div class="info-value" id="server-process-start-time">--</div>
              </div>
              <div class="info-item">
                <div class="info-label">运行时间</div>
                <div class="info-value" id="server-process-uptime">--</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- 工作节点列表 -->
    <section>
      <h2 class="text-xl font-semibold mb-4 flex items-center">
        <i class="fa fa-users text-info mr-2"></i>Worker Node
      </h2>
      <div id="workers-container" class="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 gap-6">
        <!-- 工作节点卡片将通过JavaScript动态生成 -->
      </div>
    </section>
  </main>

  <footer class="bg-white border-t border-gray-200 mt-12 py-4">
    <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
      <p>系统节点监控面板 &copy; 2025</p>
    </div>
  </footer>

  <script>
    // 根据使用率获取颜色类名
    function getUsageColor(usage) {
      if (usage > 80) return 'text-danger';
      if (usage > 50) return 'text-warning';
      return 'text-success';
    }

    // 生成工作节点卡片
    function createWorkerCard(worker) {
      const isRunning = worker.target_process.is_running;
      const cpuUsage = worker.cpu.usage_percent;
      const memUsage = worker.memory.usage_percent;

      // 状态指示颜色
      const statusColor = isRunning ? 'bg-green-500' : 'bg-red-500';
      const statusText = isRunning ? '运行中' : '已停止';

      return `
        <div class="node-card overflow-hidden">
          <div class="p-5 border-b border-gray-100">
            <div class="flex justify-between items-start">
              <div>
                <h3 class="text-lg font-semibold flex items-center">
                  <span class="status-dot ${statusColor}"></span>
                  ${worker.hostname}
                </h3>
                <p class="text-gray-500 text-sm">${worker.os} ${worker.os_version}</p>
              </div>
              <span class="bg-primary/10 text-primary text-xs font-medium px-2.5 py-0.5 rounded">
                ${worker.network.ip}
              </span>
            </div>
          </div>

          <div class="p-5 space-y-4">
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div class="info-item">
                <div class="info-label">Python版本</div>
                <div class="info-value">${worker.python_version}</div>
              </div>
              <div class="info-item">
                <div class="info-label">当前时间</div>
                <div class="info-value">${worker.current_time}</div>
              </div>
              <div class="info-item">
                <div class="info-label">运行时间</div>
                <div class="info-value">${worker.uptime}</div>
              </div>
              <div class="info-item">
                <div class="info-label">进程总数</div>
                <div class="info-value">${worker.process_count}</div>
              </div>
              <!-- 添加CPU和内存使用率 -->
              <div class="info-item">
                <div class="info-label">CPU使用率</div>
                <div class="info-value ${getUsageColor(cpuUsage)}">${cpuUsage}%</div>
              </div>
              <div class="info-item">
                <div class="info-label">内存使用率</div>
                <div class="info-value ${getUsageColor(memUsage)}">${memUsage}%</div>
              </div>
            </div>

            <div class="border-t border-gray-100 pt-4 mt-4">
              <h4 class="font-medium mb-3 flex items-center">
                <i class="fa fa-cog text-primary mr-2"></i>目标进程状态
              </h4>
              <div class="space-y-3">
                <div class="info-item">
                  <div class="info-label">运行状态</div>
                  <div class="info-value ${isRunning ? 'text-green-600' : 'text-red-600'}">${statusText}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">进程ID</div>
                  <div class="info-value">${worker.target_process.pid}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">命令行</div>
                  <div class="info-value text-sm">${worker.target_process.cmdline}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">启动时间</div>
                  <div class="info-value">${worker.target_process.start_time}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">运行时间</div>
                  <div class="info-value">${worker.target_process.uptime}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      `;
    }

    // 渲染页面数据
    function renderDashboard(apiData) {
      try {
        // 更新概览统计
        document.getElementById('valid-sn').textContent = apiData.valid_sn;
        document.getElementById('failed-count').textContent = apiData.failed_count;
        document.getElementById('success-count').textContent = apiData.success;
        document.getElementById('ocr-error').textContent = apiData.ocr_error;
        document.getElementById('input_captcha_error').textContent = apiData.get_captcha_error;
        document.getElementById('today_count').textContent = apiData.today_count;
        document.getElementById('three_days_count').textContent = apiData.three_days_count;
        document.getElementById('no-active').textContent = apiData.type10002_count;

        // 渲染服务器信息
        const server = apiData.server;
        document.getElementById('server-hostname').textContent = server.hostname;
        document.getElementById('server-ip').textContent = server.network.ip;
        document.getElementById('server-os').textContent = server.os;
        document.getElementById('server-os-version').textContent = server.os_version;
        document.getElementById('server-python-version').textContent = server.python_version;
        document.getElementById('server-current-time').textContent = server.current_time;
        document.getElementById('server-uptime').textContent = server.uptime;
        document.getElementById('server-process-count').textContent = server.process_count;

        // 渲染服务器CPU和内存使用率
        const serverCpuUsage = server.cpu.usage_percent;
        const serverMemUsage = server.memory.usage_percent;
        document.getElementById('server-cpu-usage').textContent = `${serverCpuUsage}%`;
        document.getElementById('server-mem-usage').textContent = `${serverMemUsage}%`;
        document.getElementById('server-cpu-usage').className = `info-value ${getUsageColor(serverCpuUsage)}`;
        document.getElementById('server-mem-usage').className = `info-value ${getUsageColor(serverMemUsage)}`;

        // 渲染服务器进程信息
        const serverProcess = server.target_process;
        document.getElementById('server-process-status').textContent = serverProcess.status;
        document.getElementById('server-process-pid').textContent = serverProcess.pid;
        document.getElementById('server-process-cmdline').textContent = serverProcess.cmdline;
        document.getElementById('server-process-start-time').textContent = serverProcess.start_time;
        document.getElementById('server-process-uptime').textContent = serverProcess.uptime;

        // 生成工作节点卡片
        const workersContainer = document.getElementById('workers-container');
        workersContainer.innerHTML = apiData.worker.map(createWorkerCard).join('');

      } catch (error) {
        console.error('渲染节点数据失败:', error);
        alert('渲染节点数据失败，请检查数据格式');
      }
    }

    // 搜索功能
    document.getElementById('search-node').addEventListener('input', function () {
      const searchTerm = this.value.toLowerCase();
      const workerCards = document.querySelectorAll('.node-card');

      workerCards.forEach(card => {
        const hostname = card.querySelector('h3').textContent.toLowerCase();
        if (hostname.includes(searchTerm)) {
          card.style.display = 'block';
        } else {
          card.style.display = 'none';
        }
      });
    });
  </script>
</body>

</html>
"""


# 请求状态接口
def get_status_data(url):
    try:
        response = requests.get(url, timeout=10)
        if response.status_code == 200:
            return response.json()
    except Exception:
        return None
    return None


# 生成监控html页面
def gen_monitor_html(url):
    api_data = get_status_data(url)
    if api_data:
        # 创建 BeautifulSoup 对象
        soup = BeautifulSoup(template_html, 'html.parser')

        # 生成 JavaScript 代码以渲染数据
        script = f"""
        <script>
            document.addEventListener('DOMContentLoaded', function() {{
                const apiData = {json.dumps(api_data, ensure_ascii=False, separators=(',', ':'))};
                renderDashboard(apiData);
            }});
        </script>
        """

        # 将生成的 JavaScript 代码插入到 HTML 文件中
        soup.body.append(BeautifulSoup(script, 'html.parser'))

        # 将修改后的 HTML 内容保存到新文件
        file_path = os.path.join(FILE_DIR, 'monitor_data.html')
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(str(soup))
        return file_path
    return False


if __name__ == '__main__':
    gen_monitor_html('http://xx.xx.xx.xx:12356/api/health')
